<!-- //vue实现数据双向绑定的原理就是用Object.defineproperty()重新定义（set方法）对象设置属性值和（get方法）获取属性值的操纵来实现的。
//Object.property()方法的解释：Object.property(参数1，参数2，参数3) 返回值为该对象obj
//其中参数1为该对象（obj），参数2为要定义或修改的对象的属性名，参数3为属性描述符，属性描述符是一个对象，主要有两种形式：数据描述符和存取描述符。这两种对象只能选择一种使用，不能混合使用。而get和set属于存取描述符对象的属性。
//这个方法会直接在一个对象上定义一个新属性或者修改对象上的现有属性，并返回该对象。 -->

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
</head>

<body>
    <div id="myapp">
        <input v-model="message" /><br>
        <span v-bind="message"></span>
    </div>
    <script type="text/javascript">
        var model = {
            message: ""
        };
        var models = myapp.querySelectorAll("[v-model=message]");
        console.log('models------->>', models)
        for (var i = 0; i < models.length; i++) {
            models[i].onkeyup = function () {
                model[this.getAttribute("v-model")] = this.value; // model['message'] = this.value
            }
        }

        // 观察者模式 / 钩子函数
        // defineProperty 来定义一个对象的某个属性 // get 或者 set 时
        Object.defineProperty(model, "message", {
            set: function (newValue) {
                var binds = myapp.querySelectorAll("[v-bind=message]");
                console.log('binds-------->>>', binds)
                for (var i = 0; i < binds.length; i++) {
                    binds[i].innerHTML = newValue;
                };
                var models = myapp.querySelectorAll("[v-model=message]");
                for (var i = 0; i < models.length; i++) {
                    models[i].value = newValue;
                };
                this.value = newValue;
            },
            get: function () {
                return this.value;
            }
        })
    </script>
</body>

</html>